/* eslint-disable no-console */
import React, { FormEvent, useEffect, useRef, useState } from 'react';

import { ReactComponent as StarIcon } from '@/shared/icons/star.svg';
import { useMetaTag, usePreventRedirect } from '@/shared/lib/hooks';
import { Button, ButtonVariants, Snackbar } from '@/shared/ui';
import cn from 'classnames';
import { Router, useRouter } from 'next/router';
import { useSnackbar } from 'notistack';
import { useWindowSize } from 'usehooks-ts';

import { SendReview } from '../SendReview';
import cs from './CreateReview.module.scss';

const scrollToReviews = () => document.getElementById('reviews')?.scrollIntoView({ behavior: 'smooth' });

export const CreateReview = <T,>({
  star,
  textValue,
  handleSubmit,
  createReview,
  isRating,
  setTextValue,
  changed,
  id,
  isBought,
  handleDeleteRating,
  withPrevent = true,
  setStar,
}: {
  star: number;
  id?: string;
  isRating?: boolean;
  createReview: (...args: any) => Promise<T>;
  handleSubmit?: () => void;
  withPrevent?: boolean;
  handleDeleteRating?: () => void;
  changed?: boolean;
  isBought?: boolean;
  textValue: string;
  setTextValue: any;
  setStar: any;
}) => {
  const { width } = useWindowSize();

  const inputRef = useRef<HTMLTextAreaElement>(null);
  const [isShaking, setIsShaking] = useState(false);
  const [isOpenModal, setIsOpenModal] = useState(false);
  const [redirectUrl, setRedirectUrl] = useState<string | null>(null);
  const router = useRouter();
  useMetaTag(isOpenModal, '#999999');
  const handleClose = () => {
    setIsOpenModal(() => false);
  };
  const handleClear = () => {
    setTextValue('');
    setStar(0);
    handleClose();
  };

  const handleShakeStars = () => {
    setIsShaking(() => true);
    setTimeout(() => {
      setIsShaking(() => false);
    }, 600);
  };

  useEffect(() => {
    Router.events.on('routeChangeStart', setRedirectUrl);
  }, [isOpenModal]);
  const { enqueueSnackbar } = useSnackbar();
  const handleOpen = () => {
    if (width > 768) {
      scrollToReviews();
    }

    setTimeout(() => {
      setIsOpenModal(() => true);
    }, 500);
  };
  const sendData = async () => {
    if (isBought && handleSubmit) {
      handleSubmit();
      return;
    }
    if (!id) {
      return;
    }
    const value = inputRef.current?.value;

    const data: { id: number; rate: number; comment: string | null } = {
      id: +id,
      rate: star,
      comment: value?.trim() ? value : null,
    };
    try {
      await createReview(data);
      enqueueSnackbar('Отзыв отправлен', {
        variant: 'success',
        content: (key, message) => <Snackbar id={key} message={message} size="md" variant="success" />,
      });
      handleClear();
    } catch (e) {
      console.log(e);
    }
  };

  const handleSend = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    e.stopPropagation();
    if (!star && isBought) {
      handleShakeStars();
      return;
    }
    if (star === null || star === undefined || star === 0) {
      if (width > 768 && !isBought) {
        scrollToReviews();
      }
      handleShakeStars();
      return;
    }
    sendData();
  };
  const usePreventCondition = withPrevent && star > 0;
  usePreventRedirect(usePreventCondition, handleOpen);
  const handleAccept = () => {
    sendData();
    handleClear();
    setIsOpenModal(false);
    if (redirectUrl) {
      router.push(redirectUrl, undefined, { scroll: false }).then(() => {
        setRedirectUrl(null);
      });
    }
  };
  const handleCancel = () => {
    handleClear();
    if (redirectUrl) {
      router.push(redirectUrl, undefined, { scroll: false }).then(() => {
        setRedirectUrl(null);
      });
    }
  };
  const handleCancelWithoutRoute = () => {
    setIsOpenModal(false);
  };

  return (
    <>
      <form className={isBought ? cs.isBoughtForm : cs.form} onSubmit={handleSend}>
        <div className={cn(cs.stars)}>
          {[1, 2, 3, 4, 5].map((value) => (
            <div
              className={cn(
                cs.star,
                isShaking && cs.shake_left_right,
                value - 1 < Math.round(star) && cs.active,
                isBought && cs.isBought,
              )}
              key={value}
              onClick={() => setStar(value)}
            >
              <StarIcon />
            </div>
          ))}
        </div>
        <textarea
          className={cs.input}
          data-testid="textarea-comment"
          onChange={(e) => setTextValue(e.target.value)}
          placeholder="Напишите ваше мнение"
          ref={inputRef}
          value={textValue}
        />
        {isBought ? (
          <Button
            className={cs.submitYellow}
            data-testid="button-bought_send_review"
            disabled={(!textValue && !star) || (!changed && isRating)}
            type="submit"
            variant={ButtonVariants.Primary}
          >
            Отправить
          </Button>
        ) : (
          <Button
            className={cs.submit}
            data-testid="button-send_review"
            disabled={!textValue && !star}
            type="submit"
            variant={ButtonVariants.Blue}
          >
            Оставить отзыв
          </Button>
        )}
        {isRating && (
          <Button
            className={cs.delete}
            data-testid="button-delete_review"
            onClick={handleDeleteRating}
            variant={ButtonVariants.Logout}
          >
            Удалить отзыв
          </Button>
        )}
      </form>
      <SendReview
        handleCancelWithoutRoute={handleCancelWithoutRoute}
        handleClose={handleCancel}
        handleSend={handleAccept}
        handleSubmit={handleSubmit}
        isBought={isBought}
        isOpen={isOpenModal}
      />
    </>
  );
};
